/**
 * @author luguoxiang
 * @date 2022/7/5
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import { h } from 'vue';
import {
  dateFormat,
  deepCopy,
  IConfigSchema,
  IDetailSchema,
  LgText,
  LgUpload,
  LgUploadProps,
  toLabelMap,
} from '@/soar';
import { dateFmt, datetimeFmt, timeFmt } from '@/config/global';

/**
 * 生成表格配置
 * @param config
 */
export function toDetail(config: IConfigSchema<unknown> | IDetailSchema<unknown>): object {
  let detail;
  // @ts-ignore
  if (config.detail) {
    // @ts-ignore
    detail = config.detail;
    detail.params ??= config.params;
    detail = deepCopy(detail, true);
    // 基本字段复制
    detail.field ??= config.field;
    detail.label ??= config.label;
    detail.dataType ??= config.dataType;
    detail.predicate ??= config.predicate;
  } else {
    detail = deepCopy(config, true);
    delete detail.form;
    delete detail.search;
    delete detail.table;
  }
  delete detail.order;

  // 插槽处理
  if (typeof detail.slots === 'string') {
    detail.slots = { default: detail.slots };
  } else {
    detail.slots ??= {};
  }

  if (!detail.slots.default) {
    // 数据类型处理
    switch (detail.dataType) {
      case 'dict':
        if (!detail.params) {
          throw new Error(`请配置列“${detail.field}”的“params”为对应字典code`);
        }
        detail.component = LgText;
        detail.componentProps = {
          options: detail.params,
          ...detail.componentProps,
        };
        break;
      case 'datetime':
        detail.params ??= datetimeFmt;
        detail.formatter ??= (model: any, value: any) => dateFormat(value, detail.params);
        break;
      case 'date':
        detail.params ??= dateFmt;
        detail.formatter ??= (model: any, value: any) => dateFormat(value, detail.params);
        break;
      case 'time':
        detail.params ??= timeFmt;
        detail.formatter ??= (model: any, value: any) => dateFormat(value, detail.params);
        break;
      case 'enum':
        if (!detail.params) {
          throw new Error(`请配置列“${detail.field}”的“params”字段`);
        }
        const mapper = toLabelMap(detail.params);
        detail.formatter ??= (model: any, value: any) => mapper[value];
        break;
      case 'boolean':
        if (detail.params) {
          const mapper = toLabelMap(detail.params);
          detail.formatter ??= (model: any, value: any) => mapper[value];
        } else {
          detail.formatter ??= (model: any, value: any) => (value ? '是' : '否');
        }
        break;
      case 'img':
        detail.component = LgUpload;
        detail.valueProp = 'modelValue';
        if (typeof detail.componentProps !== 'function') {
          detail.componentProps = {
            valueType: detail.params ?? 'urlList',
            type: 'img',
            disabled: true,
            ...detail.componentProps,
          } as LgUploadProps;
        }
        break;
      case 'file':
        detail.component = LgUpload;
        detail.valueProp = 'modelValue';
        if (typeof detail.componentProps !== 'function') {
          detail.componentProps = {
            valueType: detail.params ?? 'infoList',
            disabled: true,
            ...detail.componentProps,
          } as LgUploadProps;
        }
        break;
      default:
        break;
    }
  }

  if (typeof detail.formatter !== 'function') {
    detail.formatter = (model: any, value: any) => value;
  }

  if (detail.component) {
    detail.valueProp ??= 'modelValue';
  }

  return detail;
}

/**
 * 获取表格配置
 * @param fieldList
 */
export function getDetails(fieldList: Array<IConfigSchema<unknown> | IDetailSchema<unknown>>): object[] {
  return (
    fieldList
      // 过滤
      .filter((x: any) => x.detail !== false)
      // 排序
      .sort((a, b) => {
        // @ts-ignore
        if (a.detail) {
          // @ts-ignore
          a = a.detail;
        }
        // @ts-ignore
        if (b.detail) {
          // @ts-ignore
          b = b.detail;
        }
        return (a.order ?? 0) - (b.order ?? 0);
      })
      // 解析
      .map(toDetail)
      .filter((x: any) => x.predicate?.() !== false)
  );
}

export const Div = h('div');
